/**
 * Created by Qingger Corp.
 * User: jsspf
 * Date: 2017/11/23
 * Time: 23:38
 */

//// 规则1 : 声明性代码通常比命令式代码更干净
//// 无论我们的语言和我们的库或框架允许我们达到什么程度，我们都应该尽可能使用声明性的和自解释的代码。
/**
 * Note :
 *  1) 声明式代码，强调一段代码的输出结果
 *     一般来说，命令“机器”如何去做事情(how)，这样不管你想要的是什么(what)，它都会按照你的命令实现。
 *  2) 命令式代码，注重的是如何得到结果。
 *     一般来说，告诉“机器”你想要的是什么(what)，让机器想出如何去做(how)
 *
 *  @see https://juejin.im/entry/594762758d6d81cc72f0e5f9
 *
 */


// 命令式代码举例
function  commandFoo1(params:any[]) {
    var x = params[0];
    var y = params[1];
    var z = params[2]
}

// 命令式 : 求列表中每个元素的倍数
function doDoubleNumber1() {
    let numbers = [1,2,3,4,5];
    var doubled = [];
    for (let i=0;i<numbers.length;i++) {
        doubled.push(numbers[i]*2);
    }
    return doubled;
}

// 命令式，求列表的总和
function doTotalNumInList1() {
    let numbers = [1,2,3,4,5];
    let total = 0;
    numbers.forEach(function(numItem:number){
        total += numItem;
    });
    return total;
}

///=========================================================

// 声明式代码举例(参数解构)
function declareFoo1([x, y, ...args]) {
    console.log(x, y,...args);
}
function declareFoo2({x,y} : {x:number,y:number}) {
    console.log(x, y);
}
//declareFoo2({x:1,y:2});

/**
 * 声明式：求列表中每个元素的倍数
 * 将执行的行为从数据中进行抽离。
 * 另外，map也是一个纯函数，不具有任务副作用（不会改变外部形态）
 * @returns {any[]}
 */
function doubledNumber2() {
    let numbers = [1,2,3,4,5];
    return numbers.map(function(num:number){
        return num*2;
    });
}

// 声明式，求列表的总和
// reduce函数归纳抽离了我们如何遍历数组和状态管理部分的实现，
// 提供给我们一个通用的方式来把一个list合并成一个值。我们需要做的只是指明我们想要的是什么
function doTotalNumInList2() {
    let numbers = [1,2,3,4,5];
    return numbers.reduce(function(sumTotal:number,numItem:number){
        return sumTotal+numItem;
    });
}


/// 如果我们花时间去学习(或发现)声明式的可以归纳抽离的部分，它们能为我们的编程带来巨大的便捷。
/// 1) 可以少写代码，这就是通往成功的捷径
/// 2) 能让我们站在更高的层面是思考，站在云端思考我们想要的是什么，而不是站在泥里思考事情该如何去做